

AutoHref = (function(){
  
  var selection, selectionText, selectionButton, newRange, contextUrl = '<%=contextUrl%>', selector = '<%=selector%>' || 'body';
  var tbWidth = 630, tbHeight = 440;
  var buttonStyle = "margin:10px 0 0 10px;color:#fff;max-width:260px;font:12px 'Lucida Grande',Tahoma,Arial,sans-serif,georgia,Helvetica,Verdana;position:absolute;background:rgba(64,89,142,1);padding:4px 5px;-moz-border-radius:5px;-webkit-border-radius:5px;cursor:pointer;";
    
  function tbRemove(){
    jQuery("#autohref-tb-window").fadeOut("fast",function(){jQuery('#autohref-tb-window,#autohref-tb-overlay').trigger("unload").unbind().remove();});
    document.onkeydown = "";
    document.onkeyup = "";
    return false;
  }
  
  function tbDetectMacXFF() {
    var userAgent = navigator.userAgent.toLowerCase();
    if (userAgent.indexOf('mac') != -1 && userAgent.indexOf('firefox')!=-1) {
      return true;
    }
  }
  
  function tbPosition() {
    jQuery("#autohref-tb-window").css({marginLeft: '-' + parseInt((tbWidth / 2),10) + 'px', width: tbWidth + 'px',marginTop: '-' + parseInt((tbHeight / 2),10) + 'px'});
    jQuery("#TB_window").css({});
  }
  
  function handleClick(event) {
  
    cleanUp();
    selection = getSelection();
    selectionText = selection && selection.toString().replace(/^\s+|\s+$/g, '');
    if (selectionText && selectionText.length >= 3 && selectionText.indexOf("  ") < 0) {
    	((selection.anchorNode 
    	&& (selection.anchorNode == selection.focusNode)
    	&& (selection.focusNode.nodeType == 3))
    	|| (selection.parentElement
    	&& selection.parentElement()
    	&& selection.isOnlyText))
    	&& window.setTimeout(insertButton, 200);
    }
  }
  
  function getSelection() {
    return (window.getSelection && window.getSelection()) 
    || (document.getSelection && document.getSelection())
    || (document.selection && (function(){
    	var selection = document.selection && document.selection.createRange();
    	selection.isOnlyText = !(selection.htmlText.indexOf("<") >= 0);
        selection.toString = function() { return this.text };
        return selection;
    })())
    || false;
  }
  
  function insertButton() {
    
    selectionButton = (function(){
    	   	
    	var button = jQuery('<span id="autohref-anchor-select">Request "<b id="autohref-anchor-select-b">'+selectionText+'</b>" as an in-text link.</span>');
      button.attr("style", buttonStyle);
      button.hover(function(){
		      $(this).fadeTo("fast",1);
		    },
		    function() {
		      $(this).fadeTo("fast",0.3);
		  });
	    
	    return button.get(0);
	    
	  })();
    
    if(jQuery.browser.msie) {
      var tmp = jQuery('<div/>').get(0);
      tmp.appendChild(selectionButton);
      newRange = selection.duplicate();
      newRange.setEndPoint( "StartToEnd", selection);
      newRange.pasteHTML(tmp.innerHTML);
    }
    else {
      var range = selection.getRangeAt(0);
      newRange = document.createRange();
      newRange.setStart(selection.focusNode, range.endOffset);
      newRange.insertNode(selectionButton);
    }
    
    var handler = function(e){
      if(e.button < 2){
        var pos = walk(selector, [{str: selectionText, pos: -1}]); 
        setupIframe('anchor-request?u=' + encodeURIComponent(contextUrl) + "&s=" +encodeURIComponent(selectionText)+ "&p=" + pos);
      }
    }
      
    selectionButton = jQuery('#autohref-anchor-select')
      .fadeTo("normal",0.3)
      .bind("mouseup", handler)
      .get(0);
    
  }
  
  function cleanUp(event) {
  	
  	document.normalize && document.normalize();
  	if(event && (event.target == selectionButton || event.target.parentNode == selectionButton)) return;
    newRange && newRange.pasteHTML && newRange.pasteHTML('');
    selectionButton && selectionButton.parentNode && selectionButton.parentNode.removeChild(selectionButton);
    event && event.target && (event.button < 2)&& event.target.parentNode.focus();
    selectionButton = null;
  
  }
  
  function walkElements(node, depth, textproc) {
		var skipre = /^(script|style|textarea)/i;
		var count = 0;
		while (node && depth > 0) {
      count ++;
      if (count >= 1000) {
        var handler = function() {
          walkElements(node, depth, textproc);
        };
       	setTimeout(handler, 50);
        return;
      }
      if (node.nodeType == 1) {
      	if (!skipre.test(node.tagName) && node.childNodes.length > 0) {
      	  node = node.childNodes[0];
          depth ++;
          continue;
        }
      } else if (node.nodeType == 3) {
        node = textproc(node);
      }
	    if(!node){
	      break;
	    }else if (node.nextSibling) {
        node = node.nextSibling;
      } else {
        while (depth > 0) {
          node = node.parentNode;
          depth --;
          if (node.nextSibling) {
            node = node.nextSibling;
            break;
          }
        }
      }
    }
  };
  
  function walk(selector, query) {
    
    if (!query || !query[0]) return;
	  
	  var qre = [],count = {}, returnPos;
	  var qpos = {}, qhref = {}, qid = {};
    
    jQuery.each(query, function(i, val) {
      
      qre.push(val.str);
      
      (function(arr){
        for(var i in arr){
          jQuery.each(arr[i], function(key, obj){
            (obj[val.str]) ? obj[val.str].push(val[key]) : obj[val.str] = [val[key]];
          });
        }
      })([{"pos": qpos}, {"href": qhref}, {"id": qid}]);
      
      count[val.str] = 0;
    });
    
    qre = new RegExp(qre.join("|"));
    
    var textproc = function(node) {
      var match = qre.exec(node.data);
      if (match) {
        var val = match[0];
        var node2 = node.splitText(match.index);
        var node3 = node2.splitText(val.length);
        count[val]++;
        
        if(qpos[val][0] == -1) {
          if(node.parentNode.id === "autohref-anchor-select-b")
            returnPos = count[val] - 1; 
          else 
            return node2;
        } else {
          
          var pos = (function(a, v){
            for(var i = a.length; i-- && a[i] !== v;);
              return i;
           })(qpos[val], count[val]);
           
          if( pos > -1 ){
            if(node.parentNode.tagName == 'A') 
              return node2;
            var anchor = node.ownerDocument.createElement('A');
            node.parentNode.replaceChild(anchor, node2);
            anchor.setAttribute("href", qhref[val][pos]);
            anchor.setAttribute("id", "ah-link-" + qid[val][pos]);
            anchor.appendChild(node2);
            
            var editButton = jQuery("<span/>")
              .attr("style","display:none;" + buttonStyle);
              
            jQuery("#ah-link-" + qid[val][pos])
              .append(editButton)
              .bind("mouseover", function(e){jQuery('span',this).css({display: "inline"})})
              .bind("mouseout", function(e){jQuery('span',this).hide()})
              .find("span")
                .bind("mousedown", function(e){setupIframe("anchor-edit?id=" + qid[val][pos]);return false;});
              
            return anchor;
          }
          return node2;
        }
      } else {
       return node;
      }
    };
    
	  jQuery.each(jQuery(selector).get(), function(i, elm){
	    if(elm.childNodes.length > 0)
	      walkElements(elm.childNodes[0], 1, textproc);
	  });
	  
	  tbRemove();
	  return returnPos || null; 
  };
	
  function setupIframe(action) {
       
    if(document.getElementById("TB_overlay") === null){
      jQuery("body").append("<div id='autohref-tb-overlay' style='position:fixed;z-index:100;top:0px;left:0px;height:100%;width:100%;'></div><div id='autohref-tb-window' style='position:fixed;background:#ffffff;z-index:102;color:#000000;display:none;padding:4px;-moz-border-radius:5px;-webkit-border-radius:5px;text-align:left;top:50%;left:50%;'></div>");
      jQuery("#autohref-tb-overlay").click(tbRemove);
    }
        
    if(tbDetectMacXFF()){
      jQuery("#autohref-tb-overlay").css({'background': 'url(macFFBgHack.png) repeat'});//use png overlay so hide flash
    }else{
      jQuery("#autohref-tb-overlay").css({
        'background-color':'#000',
        'filter': 'alpha(opacity=75)',
        '-moz-opacity': '0.75',
        'opacity': '0.75'
      });//use background and opacity
    }
    
    tbPosition();
    var iframeW = tbWidth - 30, iframeH = tbHeight - 45;
    jQuery("#autohref-tb-window").append("<iframe frameborder='0' hspace='0' src='/iframe/"+ action +"&nocache=" + new Date().getTime() + "' id='autohref-tb-iframe-content' name='autohref-tb-iframe-content-"+Math.round(Math.random()*1000)+"' onload='AutoHref.showIframe()' style='width:"+(iframeW + 29)+"px;height:"+(iframeH + 17)+"px;' > </iframe>");      
  }
  
  function scrapeIframe(){
    jQuery("body").append("<div style='display:none'><iframe src='/iframe/scrape' onload='jQuery(\""+ selector+"\").text()'></iframe></div>");
  }
  
  function showIframe(){
    jQuery("#autohref-tb-window").css({display:"block"});
  }
  
  function removeAnchor(id, removeIframe){
    jQuery("#ah-link-" + id).replaceWith(jQuery("#ah-link-" + id).text());
    document.normalize && document.normalize();
    if(removeIframe) tbRemove();
  }
  
  return {
    
    initialize: function() {
      jQuery(selector).bind('mouseup', handleClick);
      jQuery('*').bind('mousedown', cleanUp);
    },
    
    showIframe: function() {
      showIframe();
    },
    
    removeAnchor: function(id, removeIframe) {
      removeAnchor(id, removeIframe)
    },
    
    makeAnchors: function(query){
      walk(selector, query);
    }
  };
  
})();

AutoHref.initialize();

jQuery(document).ready(function(){
  AutoHref.makeAnchors(<%=contextAnchors.toSource()%>);
});
